{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 函数"
   ]
  },
  {
   "cell_type": "markdown",
   "source": [
    "'''\n",
    "函数是组织好的，可重复使用的，用来实现单一，或相关联功能的代码段。\n",
    "\n",
    "函数能提高应用的模块性，和代码的重复利用率。你已经知道Python提供了许多内建函数，比如print()。但你也可以自己创建函数，这被叫做用户自定义函数。\n",
    "\n",
    "\n",
    "定义一个函数\n",
    "你可以定义一个由自己想要功能的函数，以下是简单的规则：\n",
    "\n",
    "函数代码块以 def 关键词开头，后接函数标识符名称和圆括号()。\n",
    "任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。\n",
    "函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。\n",
    "函数内容以冒号起始，并且缩进。\n",
    "return [表达式] 结束函数，选择性地返回一个值给调用方。不带表达式的return相当于返回 None。\n",
    "\n",
    "\n",
    "'''\n",
    "\n",
    "\n",
    "'''\n",
    "# 语法\n",
    "\n",
    "def functionname( parameters ):\n",
    "   \"函数_文档字符串\"\n",
    "   function_suite\n",
    "   return [expression]\n",
    "\n",
    " 默认情况下，参数值和参数名称是按函数声明中定义的顺序匹配起来的。\n",
    "\n",
    "'''\n",
    "\n",
    "\n",
    "\n",
    "def printme(str):\n",
    "    print(str)\n",
    "    return\n",
    "\n",
    "printme('自定义 printme 函数输出的内容')"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "raw",
   "source": [
    "'''\n",
    "\n",
    "可更改(mutable)与不可更改(immutable)对象\n",
    "在 python 中，strings, tuples, 和 numbers 是不可更改的对象，而 list,dict 等则是可以修改的对象。\n",
    "\n",
    "不可变类型：变量赋值 a=5 后再赋值 a=10，这里实际是新生成一个 int 值对象 10，再让 a 指向它，而 5 被丢弃，不是改变a的值，相当于新生成了a。\n",
    "\n",
    "可变类型：变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改，本身la没有动，只是其内部的一部分值被修改了。\n",
    "\n",
    "python 函数的参数传递：\n",
    "\n",
    "不可变类型：类似 c++ 的值传递，如 整数、字符串、元组。如fun（a），传递的只是a的值，没有影响a对象本身。比如在 fun（a）内部修改 a 的值，只是修改另一个复制的对象，不会影响 a 本身。\n",
    "\n",
    "可变类型：类似 c++ 的引用传递，如 列表，字典。如 fun（la），则是将 la 真正的传过去，修改后fun外部的la也会受影响\n",
    "\n",
    "python 中一切都是对象，严格意义我们不能说值传递还是引用传递，我们应该说传不可变对象和传可变对象。\n",
    "\n",
    "'''"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n"
     ]
    }
   ],
   "source": [
    "# python 传不可变对象实例\n",
    "\n",
    "def ChangeInt(a):\n",
    "    a = 10\n",
    "    \n",
    "b = 2\n",
    "\n",
    "ChangeInt(b)\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "函数内取值 ： [30, 40, 50, [1, 2, 3, 4]]\n",
      "函数外取值： [30, 40, 50, [1, 2, 3, 4]]\n"
     ]
    }
   ],
   "source": [
    "# 传可变对象实例\n",
    "\n",
    "def changeme( mylist ):\n",
    "    mylist.append([1,2,3,4]);\n",
    "    print('函数内取值 ：',mylist)\n",
    "    return\n",
    "mylist2 = [30,40,50];\n",
    "changeme(mylist2)\n",
    "print('函数外取值：',mylist2)\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-07-23T01:22:26.599431Z",
     "start_time": "2023-07-23T01:22:26.462497Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "My string\n",
      "Name:  miki\n",
      "Age  50\n",
      "Name:  miki\n",
      "Age  50\n",
      "Name:  miki\n",
      "Age  35\n"
     ]
    }
   ],
   "source": [
    "'''\n",
    "\n",
    "必备参数\n",
    "关键字参数\n",
    "默认参数\n",
    "不定长参数\n",
    "\n",
    "'''\n",
    "\n",
    "# 关键字参数\n",
    "\n",
    "#可写函数说明\n",
    "def printme( str ):\n",
    "   \"打印任何传入的字符串\"\n",
    "   print(str);\n",
    "   return\n",
    " \n",
    "#调用printme函数\n",
    "printme( str = \"My string\");\n",
    "\n",
    "\n",
    "# 关键字参数顺序不重要展示得更清楚：\n",
    "#可写函数说明\n",
    "def printinfo( name, age ):\n",
    "   \"打印任何传入的字符串\"\n",
    "   print (\"Name: \", name);\n",
    "   print (\"Age \", age);\n",
    "   return;\n",
    " \n",
    "#调用printinfo函数\n",
    "printinfo( age=50, name=\"miki\" );\n",
    "\n",
    "\n",
    "#可写函数说明  默认参数\n",
    "def printinfo( name, age = 35 ):\n",
    "   \"打印任何传入的字符串\"\n",
    "   print (\"Name: \", name);\n",
    "   print (\"Age \", age);\n",
    "   return;\n",
    " \n",
    "#调用printinfo函数\n",
    "printinfo( age=50, name=\"miki\" );\n",
    "printinfo( name=\"miki\" );\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "输出: \n",
      "10\n",
      "输出: \n",
      "70\n",
      "60\n",
      "50\n"
     ]
    }
   ],
   "source": [
    "# 不定长参数\n",
    "# 你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数，和上述2种参数不同，声明时不会命名。基本语法如下：\n",
    "'''\n",
    "def functionname([formal_args,] *var_args_tuple ):\n",
    "   \"函数_文档字符串\"\n",
    "   function_suite\n",
    "   return [expression]\n",
    "   \n",
    "加了星号（*）的变量名会存放所有未命名的变量参数。不定长参数实例如下：\n",
    "\n",
    "'''\n",
    "\n",
    "def printinfo( arg1, *vartuple ):\n",
    "   \"打印任何传入的参数\"\n",
    "   print(\"输出: \")\n",
    "   print(arg1)\n",
    "   for var in vartuple:\n",
    "      print(var)\n",
    "   return;\n",
    " \n",
    "# 调用printinfo 函数\n",
    "printinfo( 10 );\n",
    "printinfo( 70, 60, 50 );"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 匿名函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "lambda sum函数 结果： 30\n",
      "total =  100\n",
      "numSUM返回结果为： 100\n"
     ]
    }
   ],
   "source": [
    "'''\n",
    "\n",
    "python 使用 lambda 来创建匿名函数。\n",
    "\n",
    "lambda只是一个表达式，函数体比def简单很多。\n",
    "lambda的主体是一个表达式，而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。\n",
    "lambda函数拥有自己的命名空间，且不能访问自有参数列表之外或全局命名空间里的参数。\n",
    "虽然lambda函数看起来只能写一行，却不等同于C或C++的内联函数，后者的目的是调用小函数时不占用栈内存从而增加运行效率。\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "语法\n",
    "lambda [arg1 [,arg2,.....argn]]:expression\n",
    "\n",
    "\n",
    "'''\n",
    "\n",
    "\n",
    "\n",
    "sum = lambda arg1,arg2:arg1+arg2\n",
    "print('lambda sum函数 结果：',sum(10,20))\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "'''\n",
    "\n",
    "return 语句\n",
    "return语句[表达式]退出函数，选择性地向调用方返回一个表达式。不带参数值的return语句返回None。之前的例子都没有示范如何返回数值，下例便告诉你怎么做：\n",
    "\n",
    "\n",
    "'''\n",
    "def numSUM(arg1,arg2):\n",
    "    total = arg1 + arg2\n",
    "    print('total = ',total)\n",
    "    return total\n",
    "\n",
    "result = numSUM(40,60)\n",
    "\n",
    "print('numSUM返回结果为：',result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "函数内是局部变量 :  30\n",
      "函数外是全局变量 :  0\n"
     ]
    }
   ],
   "source": [
    "# 全局变量和局部变量\n",
    "\n",
    "total = 0; # 这是一个全局变量\n",
    "# 可写函数说明\n",
    "def sum( arg1, arg2 ):\n",
    "   #返回2个参数的和.\"\n",
    "   total = arg1 + arg2; # total在这里是局部变量.\n",
    "   print(\"函数内是局部变量 : \", total)\n",
    "   return total;\n",
    " \n",
    "#调用sum函数\n",
    "sum( 10, 20 );\n",
    "print(\"函数外是全局变量 : \", total)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
